﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsGame1
{
    class Cell
    {
        public const bool WALL = true;
        private bool top, bottom, left, right, isLockedTop, isLockedBottom, isLockedLeft, isLockedRight, isInMaze;
        private int x, y;
        private Wall topWall;
        private Wall bottomWall;
        private Wall rightWall;
        private Wall leftWall;
        List<Wall> allWalls;
        List<Wall> upWalls;
        bool markedDuringBFS;
        private Cell previousCellForBFS;

        public Cell(int x, int y)
        {
            top = bottom = left = right = WALL;
            isInMaze = false;
            this.x = x;
            this.y = y;
            allWalls = new List<Wall>();
            upWalls = new List<Wall>();
            markedDuringBFS = false;
            previousCellForBFS = null;
        }

        public bool GetWall(CellSide side)
        {
            switch (side)
            {
                case CellSide.TOP:
                    return top;
                case CellSide.BOTTOM:
                    return bottom;
                case CellSide.RIGHT:
                    return right;
                default:
                    return left;
            }
        }

        public void setPreviousCellForBFS(Cell c)
        {
            previousCellForBFS = c;
        }

        public Cell getPreviousCellForBFS()
        {
            return previousCellForBFS;
        }

        public void markForBFS() 
        {
            markedDuringBFS = true;
        }

        public void unmarkFromBFS() 
        {
            markedDuringBFS = false;
        }

        public bool isMarkedForBFS()
        {
            return markedDuringBFS;
        }

        public int GetX()
        {
            return x;
        }

        public int GetY()
        {
            return y;
        }

        public void SetInMaze(bool inMaze)
        {
            isInMaze = inMaze;
        }

        public bool IsInMaze()
        {
            return isInMaze;
        }

        public void LockTop()
        {
            isLockedTop = true;
        }

        public void LockBottom()
        {
            isLockedBottom = true;
        }

        public void LockRight()
        {
            isLockedRight = true;
        }

        public void LockLeft()
        {
            isLockedLeft = true;
        }

        public void Set(CellSide edge, bool state)
        {
            switch (edge)
            {
                case CellSide.TOP:
                    {
                        if (!isLockedTop)
                        {
                            top = state;
                        }
                        break;
                    }
                case CellSide.BOTTOM:
                    {
                        if (!isLockedBottom)
                        {
                            bottom = state;
                        }
                        break;
                    }
                case CellSide.LEFT:
                    {
                        if (!isLockedLeft)
                        {
                            left = state;
                        }
                        break;
                    }
                default:
                    {
                        if (!isLockedRight)
                        {
                            right = state;
                        }
                        break;
                    }
            }

        }

        public bool IsLocked(CellSide edge)
        {
            switch (edge)
            {
                case CellSide.TOP:
                    {
                        return isLockedTop;
                    }
                case CellSide.BOTTOM:
                    {
                        return isLockedBottom;
                    }
                case CellSide.LEFT:
                    {
                        return isLockedLeft;
                    }
                default:
                    {
                        return isLockedRight;
                    }
            }
        }

        internal IEnumerable<Wall> GetUpWalls()
        {
            return upWalls;
        }

        internal IEnumerable<Wall> GetAllWalls()
        {
            return allWalls;
        }

        internal void InitializeWalls()
        {
            topWall = new  Wall(this, CellSide.TOP);
            bottomWall = new Wall(this, CellSide.BOTTOM);
            rightWall = new Wall(this, CellSide.RIGHT);
            leftWall = new Wall(this, CellSide.LEFT);
            allWalls.Add(topWall);
            allWalls.Add(bottomWall);
            allWalls.Add(rightWall);
            allWalls.Add(leftWall);
        }

        internal void UpdateUpWalls()
        {
            upWalls.Clear();
            if (top) upWalls.Add(topWall);
            if (bottom) upWalls.Add(bottomWall);
            if (right) upWalls.Add(rightWall);
            if (left) upWalls.Add(leftWall);
        }
    }
}
